using System;
using System.Threading;
using System.Collections.Generic;

namespace Dida
{
	public class Handle : IComparable
	{
		static long nextIndex = 0;

		object obj = null;

		// the index of this handle. It doesn't really have a meaning, 
		// but it's used to give the handles an order, so that it can
		// be an IComparable, (and so it can be used in a Set<T>)
		long index;

		public Handle(object obj)
		{
			this.obj = obj;

			index = Interlocked.Increment(ref nextIndex);
		}

		public object Value
		{
			get { return obj; }
			set
			{
				obj = value;
			}
		}

		public int CompareTo(object obj)
		{
			return index.CompareTo(((Handle)obj).index);
		}
	}

	public class Handle<T> : Handle
	{
		public Handle(T obj)
			: base(obj)
		{
		}

		public new T Value
		{
			get { return (T)base.Value; }
			set { base.Value = value; }
		}
	}

	public class DerefHandleEnumerator<T> : IEnumerator<T>
	{
		IEnumerator<Handle<T>> e;

		public DerefHandleEnumerator(IEnumerator<Handle<T>> e)
		{
			this.e = e;
		}

		public T Current
		{
			get { return e.Current.Value; }
		}

		public void Dispose()
		{
			e.Dispose();
		}

		object System.Collections.IEnumerator.Current
		{
			get { return e.Current.Value; }
		}

		public bool MoveNext()
		{
			return e.MoveNext();
		}

		public void Reset()
		{
			e.Reset();
		}
	}
}